﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using JigLibX.Collision;
using JigLibX.Physics;
using JigLibX.Geometry;
using JigLibX.Math;

namespace DARE
{
    public class CPhysicCylinder : APhysicObject
    {

    #region fields

        private float m_length;
        private float m_diameter;

    #endregion

    #region properties

        public float Length { get { return m_length; } }
        public float Diameter { get { return m_diameter; } }

    #endregion

        #region ctor

        public CPhysicCylinder()
        {
            Initialize(2.0f, 0.5f);
        }

        public CPhysicCylinder(float length, float diameter)
        {
            Initialize(length, diameter);
        }

        private void Initialize(float length, float diameter)
        {
            m_length = length;
            m_diameter = diameter;

            Matrix orientation = Matrix.Identity;

            m_body = new Body();
            m_collisionSkin = new CollisionSkin(m_body);

            Capsule middle = new Capsule(Vector3.Zero, orientation, diameter / 2.0f, length - diameter);
            float sideLength = diameter / (float)Math.Sqrt(2.0d);
            Vector3 sides = new Vector3(-0.5f * sideLength, -0.5f * sideLength, -diameter / 2.0f);

            Box supply0 = new Box(sides, orientation, 
                new Vector3(sideLength, sideLength, length));
            Box supply1 = new Box(Vector3.Transform(sides, Matrix.CreateRotationZ(MathHelper.PiOver4)), 
                orientation * Matrix.CreateRotationZ(MathHelper.PiOver4), new Vector3(sideLength, sideLength, length));

            m_collisionSkin.AddPrimitive(middle, new MaterialProperties(0.8f, 0.8f, 0.7f));
            m_collisionSkin.AddPrimitive(supply0, new MaterialProperties(0.8f, 0.8f, 0.7f));
            m_collisionSkin.AddPrimitive(supply1, new MaterialProperties(0.8f, 0.8f, 0.7f));
            m_body.CollisionSkin = m_collisionSkin;

            Vector3 com = SetMass(1.0f);
            m_collisionSkin.ApplyLocalTransform(new Transform(-com, Matrix.Identity));

            float cylinderMass = m_body.Mass;
            float comOffs = (length - 2.0f * diameter / 2.0f) * 0.5f;
            float Ixx = 0.5f * cylinderMass * (diameter / 2.0f) * (diameter / 2.0f) + cylinderMass * comOffs * comOffs;
            float Iyy = 0.25f * cylinderMass * (diameter / 2.0f) * (diameter / 2.0f) + (1.0f / 12.0f) * cylinderMass * 
                length * length + cylinderMass * comOffs * comOffs;
            float Izz = Iyy;

            m_body.SetBodyInertia(Ixx, Iyy, Izz);
            m_body.EnableBody();

            m_basicModel = new CCylinderModel("mCylinder", length, diameter);
        }

        public override APhysicObject Clone()
        {
            CPhysicCylinder clone = new CPhysicCylinder(m_length, m_diameter);

            base.CopyPropertiesTo(clone);
            return clone;
        }

    #endregion

    }
}
